package com.tifa.servlet;

import com.tifa.myssm.ioc.BeanFactory;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * @Classname DispatcherServlet
 * @Description
 * @Date 2022/2/13 21:55
 * @Created by hengyuan
 */
@WebServlet("*.do")
public class DispatcherServlet extends ViewBaseServlet {
    private BeanFactory beanFactory;

    @Override
    public void init() throws ServletException {
        super.init();
        ServletContext application = getServletContext();
        Object beanFactoryObj = application.getAttribute("beanFactory");
        if (beanFactoryObj != null) {
            beanFactory = (BeanFactory) beanFactoryObj;
            System.out.println("初始化容器成功");
        } else {
            throw new RuntimeException("IOC容器获取失败");
        }
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String servletPath = req.getServletPath();
        var lastDoIndex = servletPath.lastIndexOf(".do");
        servletPath = servletPath.substring(1, lastDoIndex);
        Object controllerBeanObj = beanFactory.getBean(servletPath);
        String operate = req.getParameter("operate");
        if (StringUtils.isEmpty(operate)) {
            operate = "index";
        }
        //执行 controllerBeanObj 中的所有方法
        Method[] declaredMethods = controllerBeanObj.getClass().getDeclaredMethods();
        for (var method : declaredMethods) {
            if (!StringUtils.equals(operate, method.getName())) {
                continue;
            }
            Parameter[] parameters = method.getParameters();
            Object[] parameterValues = new Object[parameters.length];
            for (int i = 0; i < parameters.length; i++) {
                String parameter = parameters[i].getName();
                if (StringUtils.equals(parameter, "request")) {
                    parameterValues[i] = req;
                } else if (StringUtils.equals(parameter, "response")) {
                    parameterValues[i] = resp;
                } else if (StringUtils.equals(parameter, "session")) {
                    parameterValues[i] = req.getSession();
                } else {
                    //请求分页的页数
                    String parameterValue = req.getParameter(parameter);
                    String typeName = parameters[i].getType().getName();
                    Object parameterObj = parameterValue;
                    if (parameterObj != null) {
                        if ("java.lang.Integer".equals(typeName)) {
                            parameterObj = Integer.parseInt(parameterValue);
                        }
                    }
                    parameterValues[i] = parameterObj;
                }
            }
            method.setAccessible(true);
            try {
                Object returnObj = method.invoke(controllerBeanObj, parameterValues);
                String methodReturnStr = (String) returnObj;
                if (StringUtils.startsWith(methodReturnStr, "redirect:")) {
                    String redirectStr = methodReturnStr.substring("redirect:".length());
                    resp.sendRedirect(redirectStr);
                } else {
                    super.processTemplate(methodReturnStr, req, resp);
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("DispatcherSerlvet出错了");
            }
        }
    }
}
